#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"
#include "Daemon.hpp"

using cal_t = std::function<Response(Request)>;

class Parse
{
public:
    Parse(cal_t cal)
        : _cal(cal)
    {
    }

    std::string Entry(std::string &package)
    {
        // 1.判断报文的完整性
        std::string content;
        std::string respstr;
        while (Decode(package, &content))
        {
            LOG(LogLevel::DEBUG) << "content:\n"
                                 << content;

            // 2.反序列化
            Request req;
            if (!req.Deserialize(content))
                break;

            // 3.计算
            Response resp = _cal(req);

            // 4.序列化
            std::string res;
            resp.Serialize(res);
            LOG(LogLevel::DEBUG) << "序列化:\n"
                                 << res;

            // 5.添加报头
            Encode(res);

            LOG(LogLevel::DEBUG) << "Encode:\n"
                                 << res;
            respstr += res;
        }
        return respstr;
    }

private:
    cal_t _cal;
};

int main()
{
    // ENABLE_CONSOLE_LOG();
    ENABLE_FILE_LOG();
    Daemon(false, false);

    // 1.计算模块
    Calculator mycal;

    // 2.解析模块
    Parse myparse([&mycal](const Request& req){
        return mycal.Execute(req);
    });

    // 3.网络模块
    std::unique_ptr<TcpServer>svr_uptr = std::make_unique<TcpServer>(
        [&myparse](std::string& package){
            return myparse.Entry(package);
    });

    svr_uptr->InitServer();
    svr_uptr->Start();
    
    return 0;
}